﻿using Microsoft.Practices.Unity;
using System.Windows.Input;
using Microsoft.Practices.Prism.Commands;
using GermaneShanidze.Applications.Jokeri.LobbyServiceDuplexProxy;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System;
using Microsoft.Practices.Prism.Events;
using GermaneShanidze.Applications.Jokeri.Events;
using System.Collections.ObjectModel;

namespace GermaneShanidze.Applications.Jokeri.ViewModels
{
    public class LobbyChatViewModel : ViewModelBase
    {
        #region Reference to Container
        public IUnityContainer Container { get; private set; }
        private readonly IEventAggregator EvAggregator;
        #endregion Reference to Container

        public string CurrentChatMessage { get; set; }

        public ObservableCollection<string> ChatMessages { get; set; }

        public ICommand SendChatMessage { get; private set; }

        private DuplexServiceClient lobbyDuplexService;
        private CustomBinding binding = new CustomBinding(
            new PollingDuplexBindingElement(),
            new BinaryMessageEncodingBindingElement(),
            new HttpTransportBindingElement());

        public LobbyChatViewModel(IUnityContainer container, IEventAggregator eventAggregator)
        {
            // Populate property injection variables
            Container = container;
            EvAggregator = eventAggregator;

            this.SendChatMessage = new DelegateCommand(SendDuplexChatMessage);

            // Bind DuplexServiceClient acions
            lobbyDuplexService = new DuplexServiceClient(binding, new EndpointAddress("http://localhost:53434/FileSendService.svc"));
            lobbyDuplexService.SendToClientReceived += new EventHandler<SendToClientReceivedEventArgs>(DuplexServiceSendToClientReceived);
            lobbyDuplexService.SendToServiceCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(DuplexServiceSendToServiceCompleted);

            // Create own table once Facebook User Id is available
            // i.e. Subscribe CreateOwnTable to FacebookUserIdPopulatedEvent
            EvAggregator.GetEvent<FacebookUserIdPopulatedEvent>().Subscribe(this.CreateOwnTable);

            ChatMessages = new ObservableCollection<string>();
            ChatMessages.Add("One");
            ChatMessages.Add("Two");
        }

        public void CreateOwnTable(string userId)
        {
            HostSessionMessage hsm = new HostSessionMessage();
            hsm.Username = userId;
            lobbyDuplexService.SendToServiceAsync(hsm);
        }

        private void SendDuplexChatMessage()
        {
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.IsPublic = true;
            chatMessage.Message = CurrentChatMessage;
            lobbyDuplexService.SendToServiceAsync(chatMessage);
        }

        private void DuplexServiceSendToClientReceived(object sender, SendToClientReceivedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.msg is ClientConnectedMessage)
                {
                    ClientConnectedMessage msg = (ClientConnectedMessage)e.msg;
                    //AddMsgToListbox(msg.Username + " has just connected.");
                    //connectedTo = msg.Username;
                    //UIState = UIState.Chat;
                }

                else if (e.msg is HostSessionServerMessage)
                {
                    HostSessionServerMessage hssm = e.msg as HostSessionServerMessage;
                    if (hssm.Failed)
                    {
                        //MessageBox.Show("Could not create session.  Please try again later or try entering a different user name.");
                        return;
                    }
                    //SessionCreated(hssm);

                }
                else if (e.msg is JoinSessionServerMessage)
                {
                    JoinSessionServerMessage jssm = e.msg as JoinSessionServerMessage;
                    if (jssm.Failed)
                    {
                        //MessageBox.Show("Failed to Connect");
                        return;
                    }
                    //SessionJoined(jssm);
                }
                else if (e.msg is FileBeginUploadMessage)
                {
                    FileBeginUploadMessage fsm = (FileBeginUploadMessage)e.msg;

                    //int sizeInKB = (int)fsm.TotalBytes / 1024;
                    //totalRevd = 0;
                    //if (MessageBox.Show(connectedTo + " would like to send you the file: " + fsm.FileName + ", Size: " + sizeInKB + " KB.  Would you like to receive this file?", "File Upload", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    //{
                    //    bytesReceived = new List<byte>((int)fsm.TotalBytes);

                    //    fileNameReceiving = fsm.FileName;
                    //    totalFileSize = fsm.TotalBytes;
                    //    fileProgress.Value = 0;
                    //    AddMsgToListbox("File download started: " + fsm.FileName);
                    //    UIState = UIState.FileReceiving;
                    //    btnSendFile.IsEnabled = false;
                    //    tbFileStatus.Text = "Receiving File: " + fsm.FileName;
                    //}
                    //else
                    //{
                    //    fileDuplexService.SendToServiceAsync(new SendToService(new FileDenyMessage()));
                    //}
                }
                else if (e.msg is FileTransferBytesMessage)
                {
                    //if (bytesReceived == null)
                    //    return;
                    FileTransferBytesMessage fm = (FileTransferBytesMessage)e.msg;
                    //bytesReceived.AddRange(fm.Bytes);
                    //totalRevd += fm.PacketSize;
                    //double perc = ((double)totalRevd / (double)totalFileSize) * (double)100;
                    //fileProgress.Value = (int)perc;
                    //if (fm.EndFile)
                    //{
                    //    txtRecv.Text = fileNameReceiving ?? string.Empty;
                    //    UIState = UIState.FileSave;
                    //    AddMsgToListbox("File download complete, either save to disk, or click ignore to disregard file.");
                    //}
                }
                else if (e.msg is FileDenyMessage)
                {
                    //UIState = UIState.Chat;
                    //AddMsgToListbox(connectedTo + " cancelled the file transfer.");

                    //if (fileToSend != null)
                    //{
                    //    fileToSend.Close();
                    //    fileToSend = null;
                    //    btnSendFile.IsEnabled = true;
                    //}
                }
                else if (e.msg is FileReceivedMessage)
                {
                    //btnSendFile.IsEnabled = true;
                    //AddMsgToListbox(connectedTo + " finished receiving file.");
                }
                else if (e.msg is ChatMessage)
                {
                    ChatMessage msg = (ChatMessage)e.msg;
                    ChatMessages.Add(msg.Message);
                    //AddMsgToListbox(connectedTo + "> " + msg.Message);
                }
                else if (e.msg is ClientDisconnectedMessage)
                {
                    //ClientDisconnected((ClientDisconnectedMessage)e.msg);
                }
                else if (e.msg is HostDisconnectedMessage)
                {
                    //HostSessionEnded((HostDisconnectedMessage)e.msg);
                }
                else if (e.msg is GeneralError)
                {
                    //MessageBox.Show(((GeneralError)e.msg).ErrorMessage, "Error", MessageBoxButton.OK);
                }

            }
        }

        private void DuplexServiceSendToServiceCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.UserState == null)
                    return;
            }
        }

    }
}
